<script>
    let activeEffect
    class Dep {
        subscribers = new Set()

        depend() {
            if (activeEffect) {
                this.subscribers.add(activeEffect)
            }
        }
        notify() {
            this.subscribers.forEach(effect => {
                effect()
            })
        }
    }

    const targetMap = new WeakMap()

    function getMap(target, key) {
        let depsMap = targetMap.get(target)
        if (!depsMap) {
            depsMap = new Map()
            targetMap.set(target, depsMap)
        }
        let dep = depsMap.get(key)
        if (!dep) {
            dep = new Dep()
            depsMap.set(key, dep)
        }
        return dep
    }

    const reactiveHandelers = {
        get(target, key, reactiver) {
            const dep = new getMap(target, key)
            dep.depend()
            return Reflect.get(target, key, reactiver)
        },
        set(target, key, value, reactiver) {
            const dep = new getMap(target, key)
            let res = Reflect.set(target, key, value, reactiver)
            dep.notify()
            return res
        }
    }

    function reactive(raw) {
        /* ES 5方法*/
        // Object.keys(raw).forEach(key => {
        //     const dep = new Dep()
        //     let value = raw[key]
        //     Object.defineProperty(raw, key, {
        //         get() {
        //             dep.depend()
        //             return value
        //         },
        //         set(newValue) {
        //             value = newValue
        //             dep.notify()
        //         }
        //     })
        // })
        // return raw
        /*ES6方法*/
        return new Proxy(raw, reactiveHandelers)
    }

    function watchEffect(effect) {
        activeEffect = effect
        effect()
        activeEffect = null
    }


    const state = reactive({
        count: 0
    })

    watchEffect(() => {
        console.log(state.count)
    })

    state.count++
</script>